// deepclone/clone
// create/new/instanceof
// hasCycle/deepequal
// object value可迭代
// object 实现for of 可迭代
// 继承



// 示例使用
const original = {
    number: 1,
    bool: false,
    string: 'string',
    date: new Date(),
    regex: /regex/,
    array: [1, 2, 3],
    object: {
        nested: 'nested'
    },
    func: function () { console.log('hello'); }
};



function deepClone(obj, weakMap = new WeakMap()) {
    if(obj instanceof Date){
        return new Date(obj)
    }
    if(obj instanceof RegExp){
        return new RegExp(obj)
    }
    if(obj === null || typeof obj !== 'object'){
        return obj
    }

    const Constructor = obj.constructor
    const res = new Constructor();
    if(weakMap.has(obj)){
        return weakMap.get(obj)
    }
    weakMap.set(obj, res)
    Object.keys(obj).forEach(key => {
        if(obj.hasOwnProperty(key)){
            res[key] = deepClone(obj[key], weakMap)
        }
    })
    return res;
}
console.log(deepClone(original))

function clone(obj){
    if(obj instanceof Date){
        return new Date(obj)
    }
    if(obj instanceof RegExp){
        return new RegExp(obj)
    }
    if(obj === null || typeof obj !== 'object'){
        return obj
    }

    const Constructor = obj.constructor
    const res = new Constructor();

    Object.keys(obj).forEach(key => {
        if(obj.hasOwnProperty(key)){
            res[key] = obj[key]
        }
    })
    return res;
}
console.log(clone(original))



function hasCycle(obj, map = new WeakMap){
    if(obj === null || typeof obj !== 'object'){
        return false
    }
    if(map.has(obj)){
        return true
    }
    map.set(obj, true)

    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            const value = obj[key];
            if(typeof value === 'object' && hasCycle(value, map)){
                return true
            }
        }
    }
    return false
}
// 示例  
const aa = {c: 1};  
const bb = { aa };  
aa.bb = bb; // 创建循环依赖  
  
console.log(hasCycle(aa), 'hascycle'); // 输出: true  


function isObject(obj) {
    return obj !== null && typeof obj === 'object';
}

function deepEqual(obj1, obj2) {
    // 处理不同类型的比较
    if (obj1 === obj2) return true;
    // 处理一个为 null 或 undefined，另一个不是的情况
    if (!isObject(obj1) || !isObject(obj2)) return false;
    // 获取对象的键
    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);
    // 如果键的数量不同，则对象不相等
    if (keys1.length !== keys2.length) return false;
    // 检查每个键对应的值是否相等
    for (let key of keys1) {
        if (!keys2.includes(key)) {
            return false;
        }
        //  hanshu
        if (typeof [obj1][key] === 'function' && typeof [obj2][key] === 'function') {
            x = [obj1][key].toString();
            y = [obj2][key].tostring();
            return x === y
        } else {
            if (!deepEqual(obj1[key], obj2[key])) {
                return false;
            }
        }
    }
    return true;
}



// 测试用例
const objA = { a: 1, b: { c: 2 } };
const objB = { a: 1, b: { c: 2 } };
const objC = { a: 1, b: { c: 3 } };




Object.myCreate = function(obj){
    function fn (){}
    fn.prototype = obj
    return new fn()
}
console.log(Object.myCreate({a:1}))
console.log(Object.create({a:1}))

function myNew(fn, ...args){
    let newfn = Object.create(fn.prototype)
    let res = fn.call(newfn, ...args)
    return res instanceof Object ? res : newfn
}

function myInstanceOf(obj, Obj){
    let objP = Object.getPrototypeOf(obj)
    let ObjP = Obj.prototype
    while(true){
        if(objP == null) return false
        if(objP == ObjP) return true
        objP = Object.getPrototypeOf(objP)
    }
}
// 示例
function A() {}
let a1 = new A();

console.log(myInstanceOf(a1, A), '---'); // true
console.log(myInstanceOf(a1, Object)); // true
console.log(myInstanceOf(a1, Array)); // false







// const [a, b] = {a: 1, b:2} 等式可执行
Object.prototype[Symbol.iterator] = function () {
    return Object.values(this)[Symbol.iterator]()
  }


  // 对象可迭代
const myIterator = {
    data: [1, 2, 3, 4],
    [Symbol.iterator]() {
        let index = 0;
        return {
            next: () => {
                return {
                    value: this.data[index++],
                    done: index >= this.data.length
                }
            }
        }
    }
}

for (let val of myIterator) {
    console.log(val, "??")
}
console.log([...myIterator])


function inherit(son,father){
    let newson = Objcet.create(father.prototype)
    son.prototype = newson;
    son.prototype.constructor = son 
}
function Fa(){}
function Son(...args){
    Fa.call(this, ...args)
    inherit(Son, Fa)
}